package ubadb.core.components.bufferManager.bufferPool.replacementStrategies;

import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;

import ubadb.core.components.bufferManager.bufferPool.BufferFrame;
import ubadb.core.exceptions.PageReplacementStrategyException;
import ubadb.core.util.Predicate;
import ubadb.core.util.collections.CollectionUtils;
import ubadb.core.util.validation.Validate;

/**
 * Generic PageReplacementStrategy that looks for the maximum replaceable frame
 * according to a Comparator in order to pick his victim.
 */
public abstract class AbstractPageReplacementStrategy implements PageReplacementStrategy
{
	
	private final Comparator<BufferFrame> frameComparator;
	
	public AbstractPageReplacementStrategy(Comparator<BufferFrame> frameComparator)
	{
		Validate.notNull(frameComparator, "The comparator must not be null");
		this.frameComparator = frameComparator;
	}
	
	@Override
	public BufferFrame findVictim(Collection<BufferFrame> bufferFrames) throws PageReplacementStrategyException 
	{
		Collection<BufferFrame> replaceableFrames = CollectionUtils.filter(
			bufferFrames,
			new Predicate<BufferFrame>()
			{
				@Override
				public boolean evaluate(BufferFrame bufferFrame)
				{
					return bufferFrame.canBeReplaced();
				}
			}
		);
		
		if(replaceableFrames.isEmpty())
			throw new PageReplacementStrategyException("No page can be removed from pool");
		else
			return Collections.max(replaceableFrames, frameComparator);
	}
}
